<template>
  <h2>reactive的使用</h2>
  <h3>名字{{user.name}}</h3>
  <h3>年龄{{user.age}}</h3>
  <h3>性别{{user.gender}}</h3>
  <h3>妻子{{user.wife}}</h3>
  <button @click="updateUser">更新数据</button>
</template>

<script lang="ts">
import { defineComponent, reactive} from 'vue';
// 暴露出去一个定义好的组件
export default defineComponent({
  // 当前组件的名字是APP
  name: 'App',
  // 需求：显示用户的相关信息，点击按钮，可以更新用户的相关信息数据

  /*
  作用: 定义多个数据的响应式
  const proxy = reactive(obj): 接收一个普通对象然后返回该普通对象的响应式代理器对象
  响应式转换是“深层的”：会影响对象内部所有嵌套的属性
  内部基于 ES6 的 Proxy 实现，通过代理对象操作源对象内部数据都是响应式的
  */
  setup(){
    const obj:any={
      name:'小明',
      age:20,
      wife:{
        name:'小红',
        age:18,
        cars:['奔驰','宝马','奥迪']
      }
    }
    //把数据变成响应式数据，返回的是一个Proxy的代理对象
    //user是代理对象，obj是目标对象
    const user=reactive(obj)
    // 方法
    const updateUser=()=>{
      // obj.name='小军'//直接使用目标对象的方式来更新目标对象中成员的值是不能实现的，只能用代理对象的方式更新（响应式数据）
      // user.name='小花'

      // user对象或者obj对象添加一个新的属性，哪一种方式会影响界面的更新？
      // obj.gender='男'//这种方式，界面没有更新渲染
      // user.gender='男'//这种方式，界面更新渲染了，而且数据最终添加到了obj对象上

      // user对象或者obj对象移除一个已经存在的属性，哪一种方式会影响界面的更新？
      // delete obj.age//界面没有更新渲染，obj中确实没有age这个属性
      // delete user.age//界面更新渲染了，obj中没有了age属性

      // 如果操作代理对象，目标对象中的数据也会随之变化，同时界面也会更新渲染
    }
    return{
      user,
      updateUser
    }
  }
});
</script>

<style>

</style>
